package javase.spring.parser;

import javase.spring.annotation.Autowired;
import javase.spring.annotation.Controller;
import javase.spring.annotation.Service;
import javase.spring.util.FileUtil;
import org.junit.Test;

import java.awt.geom.AffineTransform;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ComponentScanParser implements ApplicationContext{

    private Map<String ,Object> beans = new HashMap<String,Object>();


    @Override
    public void config(String packageName) throws Exception {
        System.out.println("初始化,第一步:包扫描,创建容器,把对象放入容器");
        scan(packageName);
        for (String s: beans.keySet()
             ) {
            System.out.println(s+"="+beans.get(s));
        }
        System.out.println("初始化过程:对象注入");
        inject();
    }



    public void scan(String packageName) throws Exception {
        String dir = this.getClass().getResource("/").getPath();
        dir = dir + packageName.replaceAll("\\.","/");

        List<String > fileList = new ArrayList<>();
        for (String className : FileUtil.readFile(dir,fileList)
        ) {
            Class clazz = Class.forName(className);

            Controller controller = (Controller) clazz.getAnnotation(Controller.class);
            Service service = (Service) clazz.getAnnotation(Service.class);
            if (controller!=null||service!=null){
               Object Object =clazz.newInstance();
               String beanName = FileUtil.coverBeanName(className);
                beans.put(beanName,Object);
            }
        }
    }

    private void inject() throws Exception {
        for (String beanName: beans.keySet()){
            Object instance = beans.get(beanName);
            Field[] fields = instance.getClass().getDeclaredFields();
            for (Field f :fields
            ) {
                Autowired autowired =f.getAnnotation(Autowired.class);
                if (autowired!=null){
                    Object object =beans.get(f.getName());
                    f.setAccessible(true);
                    f.set(instance,object);
                }
            }
        }


    }

    @Override
     public   <T> T getBean(String beanName) {
        return (T) beans.get(beanName);
    }
}
